#pragma once

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

namespace Space_Protocol
{
    const std::string sep = "\r\n"; // 报文中的分割符
    std::string Encode(std::string &json_str)
    {
        int json_str_len = json_str.size();
        std::string proto_str = std::to_string(json_str_len);
        proto_str += sep;
        proto_str += json_str;
        proto_str += sep;

        return proto_str;
    }
    std::string Decode(std::string &net_str)
    {
        auto pos = net_str.find(sep);
        if (pos == std::string::npos)
            return std::string();

        std::string len_str = net_str.substr(0, pos);
        if (len_str.empty())
            return std::string();

        int packlen = std::stoi(len_str);
        // net_str总长为为多少时，能保证这个字符串中一定有一个合法请求
        int total = packlen + len_str.size() + 2 * sep.size();
        if (net_str.size() < total)
            return std::string();

        std::string package = net_str.substr(pos + sep.size(), packlen);
        net_str.erase(0, total);
        return package;
    }
    class Request
    {
    public:
        Request(int x, int y, char oper)
            : _x(x), _y(y), _oper(oper)
        {
        }
        Request()
        {
        }
        ~Request()
        {
        }
        bool Serialize(std::string *out)
        {
            // 将结构化数据序列号
            Json::Value root;
            root["x"] = _x;
            root["y"] = _y;
            root["oper"] = _oper;

            Json::FastWriter writer;
            *out = writer.write(root);
            return true;
        }
        bool Re_Serialize(const std::string &in)
        {

            Json::Value root;
            Json::Reader reader;
            bool ret = reader.parse(in, root);
            if (ret == false)
                return false;

            _x = root["x"].asInt();
            _y = root["y"].asInt();
            _oper = root["oper"].asInt();
            return true;
        }

        int _x;
        int _y;
        char _oper;
    };

    class Response
    {
    public:
        Response(int result, int code) : _result(result), _code(code)
        {
        }
        Response(){}
        ~Response()
        {
        }
        bool Serialize(std::string *out)
        {
            // 将结构化数据序列号
            Json::Value root;
            root["result"] = _result;
            root["code"] = _code;

            Json::FastWriter writer;
            *out = writer.write(root);
            return true;
        }
        bool Re_Serialize(const std::string &in)
        {
            Json::Value root;
            Json::Reader reader;
            bool ret = reader.parse(in, root);
            if (ret == false)
                return false;

            _result = root["result"].asInt();
            _code = root["code"].asInt();

            return true;
        }

        int _result; // 0为成功，1为除零，2、3....非法错误
        int _code;
    };
    class Factory
    {
    public:
        Factory()
        {
            srand(time(nullptr) ^ getpid());
            opers = "+-*/&]#";
        }
        std::shared_ptr<Request> BuildRequest()
        {
            int x = rand() % 10 + 1;
            usleep(x * 10);
            int y = rand() % 5 + 1;
            usleep(x * y * 23);
            char oper = opers[rand() % opers.size()];

            std::shared_ptr<Request> req = std::make_shared<Request>(x, y, oper);
            return req;
        }
        std::shared_ptr<Response> BuildResponse()
        {
            return std::make_shared<Response>();
        }

    private:
        std::string opers;
    };
}